package com.serviceprovider.business.module.report.valueobjects;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.sp.transaction.model.Batch;
import com.serviceprovider.business.module.sp.transaction.model.TransactionUserAmount;
import com.serviceprovider.business.module.user.model.impl.User;

//~--- JDK imports ------------------------------------------------------------

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class AllFeeBatchRecord {
    private List<User>                    allPayees          = new ArrayList<User>();
    private Integer                       totalAmount        = 0;
    private Double                        totalServiceFee    = 0.0;
    private List<AllFeeTransactionRecord> transactionRecords = new ArrayList<AllFeeTransactionRecord>();
    private Map<String, Integer>          totalFeeInBatch    = new HashMap<String, Integer>();
    private Batch                         batch;

    private void updatePayeesList() {
        allPayees.clear();

        Set<Integer> addedUser = new HashSet<Integer>();

        for (AllFeeTransactionRecord trans : transactionRecords) {
            for (TransactionUserAmount transUserAmount : trans.getTransactionUserAmounts()) {
                if (!addedUser.contains(transUserAmount.getUserId())) {
                    addedUser.add(transUserAmount.getUserId());
                    allPayees.add(transUserAmount.getUser());
                }
            }
        }

        Collections.sort(allPayees, new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getFullName().compareTo(o2.getFullName());
            }
        });
    }

    public void setTransactionRecords(List<AllFeeTransactionRecord> transactionRecords) {
        for (AllFeeTransactionRecord allFeeTransactionRecord : transactionRecords) {
            addTransactionRecord(allFeeTransactionRecord);
        }

        updatePayeesList();
    }

    public List<AllFeeTransactionRecord> getTransactionRecords() {
        return transactionRecords;
    }

    public void setTotalFeeInBatch(Map<String, Integer> totalFeeInBatch) {
        this.totalFeeInBatch = totalFeeInBatch;
    }

    public Map<String, Integer> getTotalFeeInBatch() {
        return totalFeeInBatch;
    }

    private void addTransactionRecord(AllFeeTransactionRecord transRecord) {
        transactionRecords.add(transRecord);

        Map<String, Integer> tranFees = transRecord.getFees();

        for (Entry<String, Integer> tranFee : tranFees.entrySet()) {
            Integer totalFee = totalFeeInBatch.get(tranFee.getKey());

            if (totalFee == null) {
                totalFee = 0;
            }

            totalFeeInBatch.put(tranFee.getKey(), (totalFee + tranFee.getValue()));
        }

        totalAmount     += transRecord.getAmount();
        totalServiceFee += transRecord.getServiceFee();
    }

    public Double getTotalFee() {
        Double total = 0.0;

        for (AllFeeTransactionRecord transRecord : transactionRecords) {
            total += transRecord.getTotalFee();
        }

        return total;
    }

    public Integer getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(Integer totalAmount) {
        this.totalAmount = totalAmount;
    }

    public List<User> getAllPayees() {
        return allPayees;
    }

    public Integer getAllPayeesSize() {
        return allPayees.size();
    }

    public List<Double> getTotalPayeeAmounts() {
        List<Double> result = new ArrayList<Double>();

        for (User payee : allPayees) {
            Double amount = 0.0;

            for (AllFeeTransactionRecord trans : transactionRecords) {
                amount += (trans.getAmountOfUser().get(payee.getId()) != null)
                          ? trans.getAmountOfUser().get(payee.getId())
                          : 0.0;
            }

            result.add(amount);
        }

        return result;
    }

    public void setBatch(Batch batch) {
        this.batch = batch;
    }

    public Batch getBatch() {
        return batch;
    }

    public Double getTotalServiceFee() {
        return totalServiceFee;
    }

    public Double getTotalCustomerBalance() {
        Double amount = 0.0;

        for (AllFeeTransactionRecord trans : transactionRecords) {
            amount += trans.getCustomerBalance();
        }

        return amount;
    }
}



